¿Es posible cambiar el contenido de document.scripts[0].firstChild con un reemplazo textual? Y de tal forma que los cambios afecten al código.
p.ej
function hamjam() { console.log("__hamjam__"); } document.scripts[0].firstChild.textContent = document.scripts[0].firstChild.textContent.replaceAll("__hamjam__", "XXX") Llamar hamjam ahora debería registrar XXX en lugar de __hamjam__ (que no lo hace).
Importante, lo que trato de hacer es altamente experimental y más una prueba de concepto que algo que trato de hacer en producción. El objetivo se puede lograr de una manera realmente fea, y si solo funciona con un determinado navegador también está bien.
Y de tal forma que los cambios afecten al código.
No. Puede cambiar el texto que está en la etiqueta del script, pero ese texto estará obsoleto cuando lo haga. Ha sido analizado en código de programa real en la memoria. Cambiarlo no tiene efecto en ese código de programa en la memoria. (De hecho, podría eliminar la etiqueta del script por completo y no tendría ningún efecto, a diferencia de la eliminación de los recursos CSS, que sí lo hace).
Aquí hay un ejemplo:
const script = document.getElementById("target-script"); script.textContent = script.textContent.replace("Hi there", "I've updated the message!"); console.log("The new script content is:"); console.log(script.textContent); console.log("But click the button and see what happens."); <input type="button" id="the-button" value="Click me"> <script id="target-script"> document.getElementById("the-button").addEventListener("click", () => { const message = "Hi there"; console.log(message); }); </script>Has dicho que tu ejemplo es solo un pequeño ejemplo de algo más grande, pero FWIW, podrías reemplazar esa función. En situaciones muy limitadas, eso podría hacer lo que desea (y, por lo tanto, probablemente no sea aplicable a su patrón más grande).
Aquí hay un ejemplo:
console.log("Calling it before the change:"); hamjam(); console.log("Changing it"); let source = Function.prototype.toString.call(hamjam); source = source.replace(/__hamjam__/g, "XXX"); hamjam = (0, eval("(" + source + ")")); console.log("Calling it after the change:"); hamjam(); <script id="target-script"> function hamjam() { console.log("__hamjam__"); } </script>Pero eso solo funciona en situaciones muy limitadas.
Function.prototype.toString tiene que devolver una representación válida de la función (lo que debería hacer en el caso normal, pero...)... y probablemente otros.
Nota al margen: Ese (0, eval("...")) puede parecer extraño si no lo ha visto antes. Como sabrá, eval tiene esta... especial... habilidad de que funciona en el ámbito local . Pero la mayoría de las veces (según mi experiencia, YMMV), no desea que el código que está evaluando tenga acceso al ámbito local. El patrón ( (0, eval("...")) ( 0 puede ser cualquier cosa) rompe el vínculo con el alcance local, haciendo la eval en el alcance global en su lugar. Se llama " eval indirecta".